package com.bub.pay.api.shiro.config;

import com.bub.pay.api.shiro.sessionDao.RedisSessionDAO;
import com.bub.pay.framework.common.config.ConditionSwaggerConfig;
import com.bub.pay.framework.shiro.authc.BcryptCredentialsMatcher;
import com.bub.pay.framework.shiro.manager.BNWebSecurityManager;
import com.bub.pay.framework.shiro.manager.BNWebSessionManager;
import com.bub.pay.framework.shiro.realm.UserRealm;
import org.apache.shiro.authz.permission.PermissionResolver;
import org.apache.shiro.authz.permission.RolePermissionResolver;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ShiroConfig {

    @Autowired(required = false)
    protected RolePermissionResolver rolePermissionResolver;

    @Autowired(required = false)
    protected PermissionResolver permissionResolver;

    //    SecurityUtils.getSubject();
    @Bean
    public UserRealm realm() {
        UserRealm userRealm = new UserRealm();
        userRealm.setCachingEnabled(false);
        userRealm.setCredentialsMatcher(new BcryptCredentialsMatcher());
        return userRealm;
    }

    @Bean
    protected BNWebSecurityManager securityManager(UserRealm userRealm, BNWebSessionManager sessionManager) {
        BNWebSecurityManager bnWebSecurityManager = new BNWebSecurityManager();
        bnWebSecurityManager.setRealm(userRealm);
        bnWebSecurityManager.setSessionManager(sessionManager);
        bnWebSecurityManager.setCacheManager(cacheManager());
//        bnWebSecurityManager.setAuthorizer(authorizer());
//        bnWebSecurityManager.setAuthenticator(authenticator());
        return bnWebSecurityManager;
    }

//    @Bean
//    protected AuthenticationStrategy authenticationStrategy() {
//        return new AtLeastOneSuccessfulStrategy();
//    }

//    @Bean
//    protected Authenticator authenticator() {
//        ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
//        authenticator.setAuthenticationStrategy(authenticationStrategy());
//        List<Realm> realms = new ArrayList<>();
//        realms.add(realm());
//        authenticator.setRealms(realms);
//        return authenticator;
//    }

    //    @Bean
//    protected Authorizer authorizer() {
//        ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
//
//        List<Realm> realms = new ArrayList<>();
//        realms.add(realm());
//        authorizer.setRealms(realms);
//        if (permissionResolver != null) {
//            authorizer.setPermissionResolver(permissionResolver);
//        }
//
//        if (rolePermissionResolver != null) {
//            authorizer.setRolePermissionResolver(rolePermissionResolver);
//        }
//
//        return authorizer;
//    }

    @Bean
    protected BNWebSessionManager sessionManager(RedisSessionDAO redisSessionDAO) {
        BNWebSessionManager sessionManager = new BNWebSessionManager();
        sessionManager.setSessionDAO(redisSessionDAO);
        return sessionManager;
    }

    @Bean
    protected RedisSessionDAO sessionDAO() {
        return new RedisSessionDAO();
    }


    @Bean
    protected CacheManager cacheManager() {
        return new MemoryConstrainedCacheManager();
    }


    /**
     * 权限框架基于servlet过滤器 Filter
     * 高纬度拦截使用ShiroFilterChainDefinition定义拦截 细粒度拦截在接口上加注解
     * 不要使用角色注解拦截 统一使用权限拦截
     * 角色  @RequiresRoles("") @RequiresRoles({"",""})
     * 权限注解 @RequiresPermissions("document:read") @RequiresPermissions({"",""})
     *
     * @return
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();

        // 角色拦截示例 admin为角色 逗号分隔
//        chainDefinition.addPathDefinition("/admin/**", "authc, roles[admin]");

        //权限拦截示例 document:read为权限 逗号分隔
//        chainDefinition.addPathDefinition("/abc/**", "authc, perms[document:read]");
        if (ConditionSwaggerConfig.isEnable()) {
            chainDefinition.addPathDefinition("/swagger-ui.html", "anon");
            chainDefinition.addPathDefinition("/swagger-resources/**", "anon");
            chainDefinition.addPathDefinition("/v2/api-docs", "anon");
            chainDefinition.addPathDefinition("/webjars/**", "anon");
        }

        // 此authc是自定义的过滤器
        chainDefinition.addPathDefinition("/**", "authc");

        return chainDefinition;
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {

        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setUsePrefix(true);
//        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);

        return defaultAdvisorAutoProxyCreator;
    }


}
